今天主要會跟大家分享如何使用NumPy 來做矩陣的應用,這在後面進行資料分析或是機器學習都有很大的幫助
此篇文是由 Joyce 所撰寫
如果想用自己的電腦來跑的話需要安裝 Package
# For anoconda (recommend)
$ conda install numpy
# For pip
$ pip install numpy
註 : CPython是一種直譯器
要使用NumPy的話,需要引入這個library,習慣上會用 np 作為縮寫
import numpy as np
最基本用來創造array的方法,常用於初始化陣列
np.array(object,
dtype = None,
copy = True,
order = None,
subok = False,
ndmin = 0)
此陣列以等差數列的形式產生,指定間隔
numpy.arange(start, stop, step, dtype)
此陣列以等差數列的形式產生,指定個數
np.linspace(start, stop,
num=50,
endpoint=True,
retstep=False,
dtype=None)
此陣列以等比數列的形式產生
np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
a = np.array([1, 2, 3]) # 建立一維陣列
b = np.array([(2, 3, 4), (5, 6, 7)]) # 建立二維陣列
c = np.arange(10) # 0到9,不包含10
d = np.arange(1, 8, 2) # 1到7,間隔為2
e = np.zeros(3) # 全是0,dtype是float
f = np.ones(3) # 全是1,dtype是float
g = np.empty(2) # 空的,但非零,有殘留值
h = np.linspace(10, 20, 5, endpoint = False) # 10到20(不包含)等差的5個數
i = np.logspace(10, 1000, 5, endpoint = True) # 10到1000(包含)等比(以10為底)的五個數
array的大小一致的話,可以直接做加減乘除的運算,其運算是元素對元素
a = np.array([1, 2, 3])
b = np.array([2, 3, 4])
# 加法,c和d同義
c = a + b
d = np.add(a, b)
# 減法,e和f同義
e = a - b
f = np.subtract(a, b)
# 乘法,g和h同義
g = a * b
h = np.multiply(a, b)
# 除法,i和j同義
i = a / b
j = np.divide(a, b)
NumPy提供的數學運算極多,這裡僅舉一些常見的例子,像是開根號、取log、高斯運算
a = np.arange(3) # 產生一個一維陣列
b = np.sqrt(a) # 對每個數值開根號
c = np.exp(a) # 以e為底,數值為指數
d = np.log(a) # 將數值取log
e = np.sin(a) # 將數值取sin
f = np.cos(a) # 將數值取cos
x = np.random.randn(3) # 隨機產生3個數值的一維陣列
y = np.random.randn(3) # 隨機產生3個數值的一維陣列
m = np.maximum(x, y) # 取出x, y中比大的數值
n = np.sign(x) # 判斷x的正負號,1.為正,-1.為負
p = np.floor(x) # 地板函數,為不大於數值的最大整數
q = np.ceil(x) # 天花板函數,為不小於數值的最小整數
在四則運算時,我們提到大小一致的話,可以直接進行運算,那如果不一致的話,難道就不行嗎?答案是可以的,只要用廣播的技巧即可
'''
First:
shape of a: (4, 3)
shape of b: (3)
Start broadcast:
b (3) -> (1, 3) # Add 1 at the first dimension
b (1, 3) -> (4, 3) # Broadcast 1 to the corresponding number
'''
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([1,2,3])
print(f"New result is {a+b}\nShape of the new result is {(a+b).shape}")
布林遮罩的意思是用一個判斷式,判斷是Ture還是Flase,常常用來做資料的分析
舉個例子來說,現在有十萬筆的薪資資料,可以使用布林遮罩的方式將大於平均薪資的資料留下
a = np.array([2, 3, 4, 5, 6, 7])
b = np.array([2, 3, 4, 5, 7, 8])
print(a == b) # 按元素判斷
print(np.array_equal(a, b)) # 按陣列判斷
x = np.array([1, 2, 3, 4, 5, 6])
print(x > 3) # 按元素判斷 [False False False True True True]
y = x[x > 3] # 將符合條件的元素取出
print(y) # [4 5 6]
x[x < 3] = 3 # 將符合條件的元素改成某值
print(x) # [3, 3, 3, 4, 5, 6]
可以利用astype的方式,將原本的type改成自己想要的type
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a.dtype) # 查看a的type int64
b = np.array([[1, 2, 3], [4, 5, 6]], dtype = np.float64)
print(b.dtype) # 查看b的type float64
c = a.astype(np.float64) # 將a的type改成float64,並指派給c
print(c.dtype) # 查看c的type float64
d = a.astype(b.dtype) # 將a的type改成跟b的type一樣,並指派給d
print(data4.dtype) # 查看d的type float64
聚合函數常常用於統計的用途,像是常見的平均值、標準差,都包含在裏頭
a = np.array([(2, 3, 4), (5, 6, 7)])
b = a.sum() # a元素的總和
c = a.sum(axis=0) # 以列為主,往下加
d = a.sum(axis=1) # 以行為主,往右加
e = a.cumsum(axis=0) # 以列為主,往下累加
f = a.cumsum(axis=1) # 以行為主,往右累加
g = a.max() # a元素的最大值
h = a.min() # a元素的最小值
i = np.median(a) # a元素的中位數
j = np.mean(a) # a元素的平均值
k = np.std(a) # a元素的標準差
l = np.var(a) # a元素的變異數
索引及切片常用來查看或改變元素。索引是利用座標的概念,找出元素,而切片,是利用slice(start, stop, step),對原陣列進行切割
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(a[0][2]) # 查看row0 查看row0 col2的元素 (3)
print(a[0,2]) # 查看row0 查看row0 col2的元素 (3)
print(a[1]) # [4 5 6] # 查看row1的所有元素
a[1] = 5 # 將row1全部改成5
print(a[1]) # [5 5 5]
a = np.arange(10)
b = slice(2,7,2) # 切出2到7(不包含),間隔維2的元素
c = a[2:7:2] # 切出a中,2到7(不包含),間隔維2的元素
print(a[b]) # [2 4 6]
print(c) # [2 4 6]
a = np.array([[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
[21, 22, 23, 24, 25]])
b = a[(0, 1, 2, 3, 4), (1, 1, 2, 3, 4)] # 取出(0,1),(1,1),(2,2),(3,3),(4,4)的元素(藍色圈圈)
c = a[2:, [0, 2]] # 取出第2列以後,第0行及第2行的所有元素(紅色圈圈)
d = a[3:, 3:] # 取出第三列以後,第3行以後的所有元素(綠色圈圈)
冒號(:) start:stop(不包含),若省略stop即代表到結尾
舉例來說
2: 表示從2開始到結束
2:5 表示從2開始到4結束
有時候為了方便,會將多維資料的矩陣,改成一維的陣列,或者其他大小,這時reshape()就派上用場了,需特別注意,改變時,元素的數目需一樣多,不然會有error喔
x = np.array([1, 2, 3, 4, 5, 6]) # x為一維陣列,員數個數是6個
y = x.reshape([2, 3]) # 將x改成2*3的矩陣,元素個數是6個,並指派給y
z = x.reshape([3, 2]) # 將x改成3*2的矩陣,元素個數是6個,並指派給z
迭代的意思是重複執行一段程式碼,例如對所有元素進行迭代,那麼就會執行到沒有元素後才會停止
a = np.arange(0,60,5) # 產生一個array,0到60(不包含),以5為間隔,有12個元素
a = a.reshape(3,4) # 將這12個元素改成3*4的矩陣
for x in np.nditer(a, order = 'C'): # 用迭代的方式讀取a裡的元素,並且以列的順序讀取
print (x, end=" " )
for x in np.nditer(a, order = 'F'): # 用迭代的方式讀取a裡的元素,並且以行的順序讀取
print (x, end=" " )
基本的矩陣運算,NumPy皆有包含,像是轉置、內積
a = np.arange(12).reshape(3,4) # 產生元素為0~12(不包含),3*4的矩陣
b = a.transpose() # 將a轉置
c = a.T # 將a轉置
d = np.dot(a, b) # 內積a*b
e = a @ b # 內積a*b
f = inv(a) # a的反函數
g = det(a) # a的行列式
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
b = np.array([3, 2, 1])
x = solve(a, b) # 解方程式 ax = b,x的值
舉例來說,現在的資料有很多id(有重複)的購買紀錄,我們想查看到底有多少id,這時用unique(),裡面元素的個數便是id數(不重複)
a = np.array([7, 2, 5, 4, 3, 6])
b = a.sort() # 將a的元素由小排到大,並指派給b
c = a.sort(reverse=True) # 將a的元素由大排到小,並指派給c
reverse預設為Flase
a = np.array([7, 2, 5, 7, 2, 6])
b = np.unique(a1) # 將a的不重複的元素取出,並指派給b
上面介紹了很多用法,看似零散,但在處理資料上,都是十分便利的工具。當然,這只是NumPy的基本知識,它還有更深更廣的用途,有興趣的話,可以去專研看看。